﻿using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class TimelineTrackControl
{
    protected const int INDENT_AMOUNT = 0x12;
    private Dictionary<TimelineItemWrapper, TrackItemControl> itemMap = new Dictionary<TimelineItemWrapper, TrackItemControl>();
    public const float ROW_HEIGHT = 17f;
    protected DirectorControlState state;
    public static TrackStyles styles;
    private TimelineTrackWrapper targetTrack;
    protected const int TRACK_ICON_WIDTH = 0x10;
    protected UnityEngine.Rect trackArea = new UnityEngine.Rect(0f, 0f, 0f, 17f);
    private TrackGroupControl trackGroupControl;

    public virtual void calculateHeight()
    {
    }

    private static int Comparison(KeyValuePair<int, TimelineItemWrapper> x, KeyValuePair<int, TimelineItemWrapper> y)
    {
        int num = 0;
        if (x.Key < y.Key)
        {
            return 1;
        }
        if (x.Key > y.Key)
        {
            num = -1;
        }
        return num;
    }

    protected void delete()
    {
        Undo.DestroyObjectImmediate(this.TargetTrack.Behaviour.gameObject);
    }

    internal static void InitStyles(GUISkin skin)
    {
        if (styles == null)
        {
            styles = new TrackStyles(skin);
        }
    }

    protected virtual void showBodyContextMenu(Event current)
    {
    }

    protected void showHeaderContextMenu()
    {
        GenericMenu menu = new GenericMenu();
        menu.AddItem(new GUIContent("Delete"), false, new GenericMenu.MenuFunction(this.delete));
        menu.ShowAsContext();
    }

    public virtual void UpdateHeaderBackground(UnityEngine.Rect position)
    {
        position.x += 18f;
        position.width -= 18f;
        GUI.Box(position, string.Empty, styles.TrackAreaStyle);
    }

    public virtual void UpdateHeaderContents(DirectorControlState state, UnityEngine.Rect position, UnityEngine.Rect headerBackground)
    {
        UnityEngine.Rect rect = new UnityEngine.Rect(position.x + 36f, position.y, position.width - 36f, position.height);
        GUI.Label(rect, this.TargetTrack.Behaviour.name);
        int controlID = GUIUtility.GetControlID(this.TargetTrack.Behaviour.GetInstanceID(), FocusType.Passive, rect);
        if (((Event.current.GetTypeForControl(controlID) == EventType.MouseDown) && rect.Contains(Event.current.mousePosition)) && (Event.current.button == 1))
        {
            this.showHeaderContextMenu();
        }
        this.updateHeaderControl1(new UnityEngine.Rect(position.width - 64f, position.y, 16f, 16f));
        this.updateHeaderControl2(new UnityEngine.Rect(position.width - 48f, position.y, 16f, 16f));
        this.updateHeaderControl3(new UnityEngine.Rect(position.width - 32f, position.y, 16f, 16f));
        this.updateHeaderControl4(new UnityEngine.Rect(position.width - 16f, position.y, 16f, 16f));
        this.updateHeaderControl5(new UnityEngine.Rect(position.width - 80f, position.y, 16f, 16f));
    }

    protected virtual void updateHeaderControl1(UnityEngine.Rect position)
    {
    }

    protected virtual void updateHeaderControl2(UnityEngine.Rect position)
    {
    }

    protected virtual void updateHeaderControl3(UnityEngine.Rect position)
    {
    }

    protected virtual void updateHeaderControl4(UnityEngine.Rect position)
    {
        if (GUI.Button(position, string.Empty, TrackGroupControl.styles.InspectorIcon))
        {
            EditorGUIUtility.PingObject(this.TargetTrack.Behaviour.gameObject.GetInstanceID());
            Selection.activeGameObject = this.TargetTrack.Behaviour.gameObject;
        }
    }

    protected virtual void updateHeaderControl5(UnityEngine.Rect position)
    {
    }

    private void updateItemMap(TimelineTrackWrapper track)
    {
        foreach (TimelineItemWrapper wrapper in track.Items)
        {
            TrackItemControl control = null;
            if (!this.itemMap.TryGetValue(wrapper, out control))
            {
                System.Type[] allSubTypes = DirectorControlHelper.GetAllSubTypes(typeof(TrackItemControl));
                System.Type type = typeof(TrackItemControl);
                int num = 0x7fffffff;
                int drawPriority = 0;
                foreach (System.Type type2 in allSubTypes)
                {
                    foreach (CutsceneItemControlAttribute attribute in type2.GetCustomAttributes(typeof(CutsceneItemControlAttribute), true))
                    {
                        if (attribute != null)
                        {
                            int subTypeDepth = DirectorControlHelper.GetSubTypeDepth(wrapper.Behaviour.GetType(), attribute.ItemType);
                            if (subTypeDepth < num)
                            {
                                type = type2;
                                num = subTypeDepth;
                                drawPriority = attribute.DrawPriority;
                            }
                        }
                    }
                }
                control = (TrackItemControl) Activator.CreateInstance(type);
                control.DrawPriority = drawPriority;
                control.TrackControl = this;
                this.itemMap.Add(wrapper, control);
            }
        }
        List<TimelineItemWrapper> list = new List<TimelineItemWrapper>();
        foreach (TimelineItemWrapper wrapper2 in this.itemMap.Keys)
        {
            bool flag = false;
            foreach (TimelineItemWrapper wrapper3 in track.Items)
            {
                if (wrapper2.Equals(wrapper3))
                {
                    flag = true;
                    break;
                }
            }
            if (!flag)
            {
                list.Add(wrapper2);
            }
        }
        foreach (TimelineItemWrapper wrapper4 in list)
        {
            this.itemMap.Remove(wrapper4);
        }
        track.HasChanged = false;
    }

    public virtual void UpdateTrackBodyBackground(UnityEngine.Rect position)
    {
        GUI.Box(position, string.Empty, styles.TrackAreaStyle);
    }

    public virtual void UpdateTrackContents(DirectorControlState state, UnityEngine.Rect position)
    {
        this.state = state;
        this.trackArea = position;
        if (this.TargetTrack.HasChanged)
        {
            this.updateItemMap(this.TargetTrack);
        }
        List<KeyValuePair<int, TimelineItemWrapper>> list = new List<KeyValuePair<int, TimelineItemWrapper>>();
        foreach (TimelineItemWrapper wrapper in this.itemMap.Keys)
        {
            TrackItemControl control = this.itemMap[wrapper];
            control.Wrapper = wrapper;
            control.Track = this.TargetTrack;
            control.PreUpdate(state, position);
            KeyValuePair<int, TimelineItemWrapper> item = new KeyValuePair<int, TimelineItemWrapper>(control.DrawPriority, wrapper);
            list.Add(item);
        }
        list.Sort(new Comparison<KeyValuePair<int, TimelineItemWrapper>>(TimelineTrackControl.Comparison));
        foreach (KeyValuePair<int, TimelineItemWrapper> pair2 in list)
        {
            this.itemMap[pair2.Value].HandleInput(state, position);
        }
        list.Reverse();
        foreach (KeyValuePair<int, TimelineItemWrapper> pair3 in list)
        {
            TrackItemControl control3 = this.itemMap[pair3.Value];
            control3.Draw(state);
            control3.PostUpdate(state);
        }
        UnityEngine.Rect rect = new UnityEngine.Rect(0f, 0f, position.width, position.height);
        int controlID = GUIUtility.GetControlID(this.TargetTrack.Behaviour.GetInstanceID(), FocusType.Passive, rect);
        if ((Event.current.GetTypeForControl(controlID) == EventType.MouseDown) && (rect.Contains(Event.current.mousePosition) && (Event.current.button == 1)))
        {
            this.showBodyContextMenu(Event.current);
            Event.current.Use();
        }
    }

    public IEnumerable<TrackItemControl> Controls
    {
        get
        {
            return this.itemMap.Values;
        }
    }

    public UnityEngine.Rect Rect
    {
        get
        {
            this.calculateHeight();
            return this.trackArea;
        }
    }

    public DirectorControlState State
    {
        set
        {
            this.state = value;
        }
    }

    public TimelineTrackWrapper TargetTrack
    {
        get
        {
            return this.targetTrack;
        }
        set
        {
            this.targetTrack = value;
        }
    }

    public TrackGroupControl TrackGroupControl
    {
        get
        {
            return this.trackGroupControl;
        }
        set
        {
            this.trackGroupControl = value;
        }
    }

    public class TrackStyles
    {
        public GUIStyle AudioTrackItemSelectedStyle;
        public GUIStyle AudioTrackItemStyle;
        public GUIStyle compressStyle;
        public GUIStyle curveCanvasStyle;
        public GUIStyle curveStyle;
        public GUIStyle editCurveItemStyle;
        public GUIStyle EventItemStyle;
        public GUIStyle expandStyle;
        public GUIStyle GlobalTrackItemSelectedStyle;
        public GUIStyle GlobalTrackItemStyle;
        public GUIStyle keyframeContextStyle;
        public GUIStyle keyframeStyle;
        public GUIStyle ShotTrackItemSelectedStyle;
        public GUIStyle ShotTrackItemStyle;
        public GUIStyle tangentStyle;
        public GUIStyle TrackAreaStyle;
        public GUIStyle TrackItemSelectedStyle;
        public GUIStyle TrackItemStyle;

        public TrackStyles(GUISkin skin)
        {
            this.TrackAreaStyle = skin.FindStyle("Track Area");
            this.TrackItemStyle = skin.FindStyle("Track Item");
            this.TrackItemSelectedStyle = skin.FindStyle("TrackItemSelected");
            this.ShotTrackItemStyle = skin.FindStyle("ShotTrackItem");
            this.ShotTrackItemSelectedStyle = skin.FindStyle("ShotTrackItemSelected");
            this.AudioTrackItemStyle = skin.FindStyle("AudioTrackItem");
            this.AudioTrackItemSelectedStyle = skin.FindStyle("AudioTrackItemSelected");
            this.GlobalTrackItemStyle = skin.FindStyle("GlobalTrackItem");
            this.GlobalTrackItemSelectedStyle = skin.FindStyle("GlobalTrackItemSelected");
            this.keyframeStyle = skin.FindStyle("Keyframe");
            this.curveStyle = skin.FindStyle("Curve");
            this.tangentStyle = skin.FindStyle("TangentHandle");
            this.curveCanvasStyle = skin.FindStyle("CurveCanvas");
            this.compressStyle = skin.FindStyle("CompressVertical");
            this.expandStyle = skin.FindStyle("ExpandVertical");
            this.editCurveItemStyle = skin.FindStyle("EditCurveItem");
            this.EventItemStyle = skin.FindStyle("EventItem");
            this.keyframeContextStyle = skin.FindStyle("KeyframeContext");
        }
    }
}

